package net.betou.cms.action.admin.main;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.betou.cms.action.admin.ActionUtils;
import net.betou.cms.entity.main.CmsModel;
import net.betou.cms.manager.main.CmsLogMng;
import net.betou.cms.manager.main.CmsModelMng;
import net.betou.cms.web.WebErrors;
import net.betou.cms.web.WebResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class CmsModelAct{
	private static final Logger log = LoggerFactory.getLogger( CmsModelAct.class );

	@RequestMapping( "/model/v_list.do" )
	public String list( String searchValue, String searchProperty, String orderProperty, String orderDirection, HttpServletRequest request, ModelMap model ) {
		// List< CmsModel > list = manager.getList( true, null );
		List< CmsModel > list = manager.getList( searchValue, searchProperty, orderProperty, orderDirection, true, null );
		model.addAttribute( "list", list );

		ActionUtils.toModelWithList( model, list, null, searchProperty, searchValue, orderProperty, orderDirection, null );

		return "model/list";
	}

	@RequestMapping( "/model/v_add.do" )
	public String add( ModelMap model ) {
		return "model/add";
	}

	@RequestMapping( "/model/v_edit.do" )
	public String edit( Integer id, HttpServletRequest request, ModelMap model ) {
		WebErrors errors = validateEdit( id, request );
		if( errors.hasErrors( ) ){
			return errors.showErrorPage( model );
		}
		model.addAttribute( "cmsModel", manager.findById( id ) );
		return "model/edit";
	}

	@RequestMapping( "/model/o_save.do" )
	public String save( CmsModel bean, HttpServletRequest request, ModelMap model ) {
		WebErrors errors = validateSave( bean, request );
		if( errors.hasErrors( ) ){
			return errors.showErrorPage( model );
		}
		bean = manager.save( bean );
		log.info( "save CmsModel id={}", bean.getId( ) );
		cmsLogMng.operating( request, "cmsModel.log.save", "id=" + bean.getId( ) + ";name=" + bean.getName( ) );
		return "redirect:v_list.do";
	}

	@RequestMapping( "/model/o_update.do" )
	public String update( CmsModel bean, HttpServletRequest request, ModelMap model ) {
		WebErrors errors = validateUpdate( bean.getId( ), request );
		if( errors.hasErrors( ) ){
			return errors.showErrorPage( model );
		}
		bean = manager.update( bean );
		log.info( "update CmsModel id={}.", bean.getId( ) );
		cmsLogMng.operating( request, "cmsModel.log.update", "id=" + bean.getId( ) + ";name=" + bean.getName( ) );
		return "redirect:v_list.do";
	}

	@RequestMapping( "/model/o_delete.do" )
	public void delete( Integer [ ] ids, HttpServletRequest request, HttpServletResponse response, ModelMap model ) {
		WebResponse res = validateDelete( ids, request, response );
		if( res.hasResponse( ) ){
			res.showResponse( );
			return;
		}
		
		CmsModel [ ] beans = manager.deleteByIds( ids );
		for ( CmsModel bean : beans ){
			log.info( "delete CmsModel id={}", bean.getId( ) );
			cmsLogMng.operating( request, "cmsModel.log.delete", "id=" + bean.getId( ) + ";name=" + bean.getName( ) );
		}
		
		res.addDeleteSuccessResponse( ids.length );
		return;
	}

	@RequestMapping( "/model/o_priority.do" )
	public String priority( Integer [ ] wids, Integer [ ] priority, Boolean [ ] disabled, Integer defId, HttpServletRequest request, ModelMap model ) {
		WebErrors errors = validatePriority( wids, priority, disabled, defId, request );
		if( errors.hasErrors( ) ){
			return errors.showErrorPage( model );
		}
		manager.updatePriority( wids, priority, disabled, defId );

		ActionUtils.alertSuccessMessage( "global.success", model );

		return list( null, null, null, null, request, model );
	}

	private WebErrors validateSave( CmsModel bean, HttpServletRequest request ) {
		WebErrors errors = WebErrors.create( request );
		return errors;
	}

	private WebErrors validateEdit( Integer id, HttpServletRequest request ) {
		WebErrors errors = WebErrors.create( request );
		if( vldExist( id, errors ) ){
			return errors;
		}
		return errors;
	}

	private WebErrors validateUpdate( Integer id, HttpServletRequest request ) {
		WebErrors errors = WebErrors.create( request );
		if( vldExist( id, errors ) ){
			return errors;
		}
		return errors;
	}

	private WebResponse validateDelete( Integer [ ] ids, HttpServletRequest request, HttpServletResponse response ) {

		WebResponse res = WebResponse.create( request, response );

		if( res.ifEmpty( ids ) ){
			res.addErrorResponse( "delete.if.empty" );
			return res;
		}

		for ( Integer id : ids ){
			if( vldExist( id, res ) ){
				return res;
			}
		}
		return res;
	}

	private WebErrors validatePriority( Integer [ ] wids, Integer [ ] priority, Boolean [ ] disabled, Integer defId, HttpServletRequest request ) {
		WebErrors errors = WebErrors.create( request );

		if( errors.ifEmpty( wids ) ){
			errors.addErrorCode( "channel.wids.empty" );
			return errors;
		}

		if( errors.ifEmpty( priority ) ){
			errors.addErrorCode( "channel.priority.empty" );
			return errors;
		}

		if( wids.length != priority.length ){
			errors.addErrorCode( "channel.wids.priority.length", priority.length, wids.length );
			return errors;
		}

		for ( int i = 0, len = wids.length; i < len; i++ ){
			if( vldExist( wids[ i ], errors ) ){
				return errors;
			}
			if( priority[ i ] == null ){
				priority[ i ] = 0;
			}
			if( disabled[ i ] == null ){
				disabled[ i ] = false;
			}
		}
		if( vldExist( defId, errors ) ){
			return errors;
		}
		return errors;
	}

	private boolean vldExist( Integer id, WebErrors errors ) {
		if( errors.ifNull( id ) ){
			errors.addErrorCode( "model.null" );
			return true;
		}

		CmsModel entity = manager.findById( id );
		if( errors.ifNotExist( entity ) ){
			errors.addErrorCode( "channel.not.exist", id );
			return true;
		}
		return false;
	}
	
	private boolean vldExist( Integer id, WebResponse res ) {
		if( res.ifNull( id ) ){
			res.addErrorResponse( "delete.if.exist" );
			return true;
		}

		CmsModel entity = manager.findById( id );

		if( res.ifNotExist( entity ) ){
			res.addErrorResponse( "delete.if.exist" );
			return true;
		}
		return false;
	}

	@Autowired
	private CmsLogMng cmsLogMng;
	@Autowired
	private CmsModelMng manager;
}